//TerrainWaterFX.h
//Created 20/02/14
//Created By Daniel Bowler
//
//Water effect used in this game

#pragma once

#include "AbstractFX.h"

class TerrainWaterFX : public AbstractFX
{
	//Ensure that the ShaderManager can access private functions - the constructor/
	//destructor. Thus, the ShaderManager will be the only class allowed to 
	//create/destroy Effects.
	friend ShaderManager;
public:
	//Per vertex structure.
	struct PerVertex
	{
		XMFLOAT3 PosL;
		XMFLOAT3 NormalL;
		XMFLOAT3 TangentL;
		XMFLOAT2 Tex;
	};

	//Sets cbuffer data
	void SetCBufferPerObject(CXMMATRIX& world, 
		CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj,
		Material& mat, 
		CXMMATRIX& worldView);

	//Set tex transforms
	void SetTexTransforms(CXMMATRIX& texTrans, CXMMATRIX& texTrans2);

	//Set lighting data.
	void SetLightingData(XMFLOAT3& eye, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* lightListIndexBuffer, 
		ID3D11ShaderResourceView* lightListStartEndBuffer);

	//Set the texture map
	void SetTextureMap(ID3D11ShaderResourceView* reflectMap,
		ID3D11ShaderResourceView* refactMap,
		ID3D11ShaderResourceView* normalMap, 
		ID3D11ShaderResourceView* envMap);

	//Sets hemispherical ambient colour data
	void SetHemisphericalData(XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange);

	//Set SSAO Map and transform data
	void SetSSAOData(ID3D11ShaderResourceView* ssaoTex, CXMMATRIX &transform);

	//Sets shadow map
	void SetShadowMap(ID3D11ShaderResourceView* shadowMap);
	void SetShadowMapMatricies(CXMMATRIX &view, CXMMATRIX &proj, CXMMATRIX &toTex);

private:
	//Changes this so the ShaderManager will handle this automatically. 
	//
	//Set render target dimension data
	void SetRTDimensions(unsigned width, unsigned height);
	//Set Light List Buffer (Global lights buffer - Shader Manager can call this)
	void SetLightListBuffer(ID3D11ShaderResourceView* lightListBuffer);

private:
	TerrainWaterFX(ID3D11Device* device);
	~TerrainWaterFX();
	//Disable copy constrcutor and assignment operator
	TerrainWaterFX(TerrainWaterFX& copy);
	TerrainWaterFX& operator=(TerrainWaterFX& other);

	//Override the init methods.
	void InitInputLayout(ID3D11Device* device);
	void InitShaderVariablePointers();

private:
	//Variables.
	//
	//Cbuffer Data:
	ID3DX11EffectMatrixVariable* worldVar;
	ID3DX11EffectMatrixVariable* worldInvTransVar;
	ID3DX11EffectMatrixVariable* worldViewProjVar;

	//Tex transforms:
	ID3DX11EffectMatrixVariable* texTransformVar;
	ID3DX11EffectMatrixVariable* texTransform2Var;

	//Render dimensions
	ID3DX11EffectScalarVariable* rtWidthVar;
	ID3DX11EffectScalarVariable* rtHeightVar;

	//Lighting data
	ID3DX11EffectVectorVariable* eyePosVar;
	ID3DX11EffectVariable* materialVar;
	//Direc Lights
	ID3DX11EffectVariable* direcLightVar;
	ID3DX11EffectScalarVariable* direcLightCountVar;
	//Point/Spot lights - Tile Forward System
	ID3DX11EffectShaderResourceVariable* llbVar;
	ID3DX11EffectShaderResourceVariable* llibVar;
	ID3DX11EffectShaderResourceVariable* llsebVar;

	//Textures
	ID3DX11EffectShaderResourceVariable* texMapReflectionVar;
	ID3DX11EffectShaderResourceVariable* texMapRefactionVar;
	ID3DX11EffectShaderResourceVariable* texNormalMapVar;
	
	//Env Map
	ID3DX11EffectShaderResourceVariable* envMapVar;

	//Hemispheric Ambient lighting colours
	ID3DX11EffectVectorVariable* hemiColDownVar;
	ID3DX11EffectVectorVariable* hemiColRangeVar;

	//SSAO
	ID3DX11EffectMatrixVariable* worldViewVar;
	ID3DX11EffectShaderResourceVariable* ssaoMapVar;
	ID3DX11EffectMatrixVariable* ssaoWorldViewProjTexVar;

	//Shadow Map
	ID3DX11EffectShaderResourceVariable* shadowMapVar;
	ID3DX11EffectMatrixVariable* shadowMapViewVar;
	ID3DX11EffectMatrixVariable* shadowMapProjVar;
	ID3DX11EffectMatrixVariable* shadowMapToTexVar;
};